package com.shop.cereshop.app.controller.wallet;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.shop.cereshop.app.param.wallet.WalletInfoVO;
import com.shop.cereshop.app.param.wallet.PayPasswordLockStatusVO;
import com.shop.cereshop.app.param.wallet.SetPayPasswordRequest;
import com.shop.cereshop.app.param.wallet.ModifyPayPasswordRequest;
import com.shop.cereshop.app.param.wallet.VerifyPayPasswordRequest;
import com.shop.cereshop.app.param.wallet.ResetPayPasswordRequest;
import com.shop.cereshop.app.param.wallet.WalletInitResult;
import com.shop.cereshop.app.param.wallet.WalletPayCheckRequest;
import com.shop.cereshop.app.param.wallet.WalletPayExecuteRequest;
import com.shop.cereshop.app.param.wallet.WalletPayCheckResult;
import com.shop.cereshop.app.param.wallet.WalletPayExecuteResult;
import com.shop.cereshop.commons.constant.WalletConstant;
import com.shop.cereshop.commons.result.Result;
import com.shop.cereshop.app.service.buyer.CereBuyerUserService;
import com.shop.cereshop.app.service.wallet.BuyerWalletService;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

/**
 * 用户钱包控制器
 */
@Slf4j
@RestController
@RequestMapping("/wallet")
@Api(tags = "用户钱包管理")
public class BuyerWalletController {

    @Autowired
    private BuyerWalletService buyerWalletService;

    @Autowired
    private CereBuyerUserService cereBuyerUserService;

    @ApiOperation("获取钱包信息")
    @GetMapping("/info")
    public Result<WalletInfoVO> getWalletInfo(HttpServletRequest request) {
        try {
            //获取当前登录账户
            CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
            if (BeanUtil.isEmpty(user)) {
                return new Result(CoReturnFormat.USER_NOT_LOGIN);
            }

            WalletInfoVO walletInfo = buyerWalletService.getWalletInfo(user.getBuyerUserId());
            return new Result(walletInfo, CoReturnFormat.SUCCESS);
        } catch (Exception e) {
            log.error("获取钱包信息失败", e);
            return new Result(CoReturnFormat.SYS_ERROR);
        }
    }

    @ApiOperation("初始化钱包")
    @PostMapping("/init")
    public Result<String> initWallet(HttpServletRequest request) {
        try {
            //获取当前登录账户
            CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
            if (BeanUtil.isEmpty(user)) {
                return new Result(CoReturnFormat.USER_NOT_LOGIN);
            }

            WalletInitResult result = buyerWalletService.initWallet(user.getBuyerUserId());
            if (result.getIsNewWallet()) {
                return new Result(true, CoReturnFormat.SUCCESS);
            } else {
                return new Result(CoReturnFormat.WALLET_ALREADY_EXISTS);
            }
        } catch (Exception e) {
            log.error("初始化钱包失败", e);
            return new Result(CoReturnFormat.WALLET_INIT_FAIL);
        }
    }

    @ApiOperation(value = "设置支付密码", notes = "设置用户支付密码，需要提供加密后的支付密码和确认密码")
    @PostMapping("/payPassword/set")
    public Result<String> setPayPassword(@ApiParam(value = "设置支付密码参数", required = true) @RequestBody SetPayPasswordRequest setPayPasswordRequest, HttpServletRequest request) {
        try {
            //获取当前登录账户
            CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
            if (BeanUtil.isEmpty(user)) {
                return new Result(CoReturnFormat.USER_NOT_LOGIN);
            }

            // 验证支付密码格式
            if (!setPayPasswordRequest.isPayPasswordValidFormat()) {
                Result<String> result = new Result<>(CoReturnFormat.PARAM_INVALID);
                result.setMessage("支付密码格式错误或解密失败");
                return result;
            }

            // 验证确认支付密码格式
            if (!setPayPasswordRequest.isConfirmPayPasswordValidFormat()) {
                Result<String> result = new Result<>(CoReturnFormat.PARAM_INVALID);
                result.setMessage("确认支付密码格式错误或解密失败");
                return result;
            }

            // 验证两次密码是否一致
            if (!setPayPasswordRequest.isPasswordMatch()) {
                return new Result(CoReturnFormat.PAY_PASSWORD_CONFIRM_ERROR);
            }

            String ipAddress = getClientIpAddress(request);
            WalletConstant.PayPasswordSetResult result = buyerWalletService.setPayPassword(user.getBuyerUserId(),
                    setPayPasswordRequest.decryptPayPassword(),
                    ipAddress);

            switch (result) {
                case SUCCESS:
                    return new Result(true, CoReturnFormat.SUCCESS);
                case ALREADY_SET:
                    return new Result(CoReturnFormat.PAY_PASSWORD_ALREADY_SET);
                case FAILED:
                default:
                    return new Result(CoReturnFormat.PAY_PASSWORD_SET_FAIL);
            }
        } catch (Exception e) {
            log.error("设置支付密码失败", e);
            return new Result(CoReturnFormat.PAY_PASSWORD_SET_FAIL);
        }
    }

    @ApiOperation("修改支付密码")
    @PostMapping("/payPassword/modify")
    public Result<String> modifyPayPassword(@RequestBody ModifyPayPasswordRequest modifyPayPasswordRequest, HttpServletRequest request) {
        try {
            //获取当前登录账户
            CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
            if (BeanUtil.isEmpty(user)) {
                return new Result(CoReturnFormat.USER_NOT_LOGIN);
            }

            // 验证旧支付密码格式
            if (!modifyPayPasswordRequest.isOldPayPasswordValidFormat()) {
                Result<String> result = new Result<>(CoReturnFormat.PARAM_INVALID);
                result.setMessage("旧支付密码格式错误或解密失败");
                return result;
            }

            // 验证新支付密码格式
            if (!modifyPayPasswordRequest.isPayPasswordValidFormat()) {
                Result<String> result = new Result<>(CoReturnFormat.PARAM_INVALID);
                result.setMessage("新支付密码格式错误或解密失败");
                return result;
            }

            // 验证确认支付密码格式
            if (!modifyPayPasswordRequest.isConfirmPayPasswordValidFormat()) {
                Result<String> result = new Result<>(CoReturnFormat.PARAM_INVALID);
                result.setMessage("确认支付密码格式错误或解密失败");
                return result;
            }

            // 验证两次密码是否一致
            if (!modifyPayPasswordRequest.isPasswordMatch()) {
                return new Result(CoReturnFormat.PAY_PASSWORD_CONFIRM_ERROR);
            }

            String ipAddress = getClientIpAddress(request);
            WalletConstant.PayPasswordModifyResult result = buyerWalletService.modifyPayPassword(user.getBuyerUserId(),
                    modifyPayPasswordRequest.decryptOldPayPassword(),
                    modifyPayPasswordRequest.decryptPayPassword(),
                    ipAddress);

            switch (result) {
                case SUCCESS:
                    return new Result(true, CoReturnFormat.SUCCESS);
                case NOT_SET:
                    return new Result(CoReturnFormat.PAY_PASSWORD_NOT_SET);
                case OLD_PASSWORD_ERROR:
                    return new Result(CoReturnFormat.PAY_PASSWORD_OLD_ERROR);
                case FAILED:
                default:
                    return new Result(CoReturnFormat.PAY_PASSWORD_MODIFY_FAIL);
            }
        } catch (Exception e) {
            log.error("修改支付密码失败", e);
            return new Result(CoReturnFormat.PAY_PASSWORD_MODIFY_FAIL);
        }
    }

    @ApiOperation("验证支付密码")
    @PostMapping("/payPassword/verify")
    public Result<String> verifyPayPassword(@RequestBody VerifyPayPasswordRequest verifyPayPasswordRequest, HttpServletRequest request) {
        try {
            //获取当前登录账户
            CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
            if (BeanUtil.isEmpty(user)) {
                return new Result(CoReturnFormat.USER_NOT_LOGIN);
            }

            // 验证支付密码格式
            if (!verifyPayPasswordRequest.isPayPasswordValidFormat()) {
                Result<String> result = new Result<>(CoReturnFormat.PARAM_INVALID);
                result.setMessage("支付密码格式错误或解密失败");
                return result;
            }

            String ipAddress = getClientIpAddress(request);
            boolean success = buyerWalletService.verifyPayPassword(user.getBuyerUserId(),
                    verifyPayPasswordRequest.decryptPayPassword(),
                    ipAddress);

            if (success) {
                return new Result(true, CoReturnFormat.SUCCESS);
            } else {
                return new Result(CoReturnFormat.PAY_PASSWORD_VERIFY_FAIL);
            }
        } catch (Exception e) {
            log.error("验证支付密码失败", e);
            return new Result(CoReturnFormat.PAY_PASSWORD_VERIFY_FAIL);
        }
    }

    @ApiOperation("重置支付密码")
    @PostMapping("/payPassword/reset")
    public Result<String> resetPayPassword(@RequestBody ResetPayPasswordRequest resetPayPasswordRequest, HttpServletRequest request) {
        try {
            //获取当前登录账户
            CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
            if (BeanUtil.isEmpty(user)) {
                return new Result(CoReturnFormat.USER_NOT_LOGIN);
            }

            // 验证新支付密码格式
            if (!resetPayPasswordRequest.isPayPasswordValidFormat()) {
                Result<String> result = new Result<>(CoReturnFormat.PARAM_INVALID);
                result.setMessage("新支付密码格式错误或解密失败");
                return result;
            }

            // 验证确认支付密码格式
            if (!resetPayPasswordRequest.isConfirmPayPasswordValidFormat()) {
                Result<String> result = new Result<>(CoReturnFormat.PARAM_INVALID);
                result.setMessage("确认支付密码格式错误或解密失败");
                return result;
            }

            // 验证两次密码是否一致
            if (!resetPayPasswordRequest.isPasswordMatch()) {
                return new Result(CoReturnFormat.PAY_PASSWORD_CONFIRM_ERROR);
            }

            String ipAddress = getClientIpAddress(request);
            boolean success = buyerWalletService.resetPayPassword(user.getBuyerUserId(),
                    resetPayPasswordRequest.getSmsCode(),
                    resetPayPasswordRequest.decryptPayPassword(),
                    ipAddress);

            if (success) {
                return new Result(true, CoReturnFormat.SUCCESS);
            } else {
                return new Result(CoReturnFormat.PAY_PASSWORD_RESET_FAIL);
            }
        } catch (Exception e) {
            log.error("重置支付密码失败", e);
            return new Result(CoReturnFormat.PAY_PASSWORD_RESET_FAIL);
        }
    }

    @ApiOperation("检查支付密码锁定状态")
    @GetMapping("/payPassword/lockStatus")
    public Result<PayPasswordLockStatusVO> checkPayPasswordLockStatus(HttpServletRequest request) {
        try {
            //获取当前登录账户
            CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
            if (BeanUtil.isEmpty(user)) {
                return new Result(CoReturnFormat.USER_NOT_LOGIN);
            }

            boolean isLocked = buyerWalletService.isPayPasswordLocked(user.getBuyerUserId());
            long remainingTime = buyerWalletService.getRemainingLockTime(user.getBuyerUserId());

            PayPasswordLockStatusVO statusVO = new PayPasswordLockStatusVO();
            statusVO.setIsLocked(isLocked);
            statusVO.setRemainingLockTime(remainingTime);

            return new Result(statusVO, CoReturnFormat.SUCCESS);
        } catch (Exception e) {
            log.error("检查支付密码锁定状态失败", e);
            return new Result(CoReturnFormat.SYS_ERROR);
        }
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0];
        }

        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }

        return request.getRemoteAddr();
    }

    @ApiOperation(value = "钱包支付余额检查", notes = "检查用户钱包余额是否足够支付订单")
    @PostMapping("/pay/check")
    public Result<String> checkWalletBalance(@ApiParam(value = "钱包支付余额检查参数", required = true) @RequestBody WalletPayCheckRequest checkRequest, HttpServletRequest request) {
        try {
            //获取当前登录账户
            CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
            if (BeanUtil.isEmpty(user)) {
                return new Result(CoReturnFormat.USER_NOT_LOGIN);
            }
            WalletPayCheckResult result = buyerWalletService.checkWalletBalanceForPay(user.getBuyerUserId(), checkRequest.getOrderId(), checkRequest.getType(), checkRequest.getCollageId());

            if (result.isSuccess()) {
                return new Result(result.getMessage(), CoReturnFormat.SUCCESS, user.getWechatName(), "钱包支付余额检查", "");
            } else {
                return new Result(result.getMessage(), result.getErrorCode(), user.getWechatName(), "钱包支付余额检查", "");
            }
        } catch (Exception e) {
            log.error("钱包支付余额检查失败", e);
            return new Result(CoReturnFormat.SYS_ERROR);
        }
    }

    @ApiOperation(value = "钱包支付执行", notes = "执行钱包支付，验证支付密码并扣款")
    @PostMapping("/pay/execute")
    public Result<String> executeWalletPay(@ApiParam(value = "钱包支付执行参数", required = true) @RequestBody WalletPayExecuteRequest executeRequest, HttpServletRequest request) {
        try {
            //获取当前登录账户
            CereBuyerUser user = (CereBuyerUser) request.getAttribute("user");
            if (BeanUtil.isEmpty(user)) {
                return new Result(CoReturnFormat.USER_NOT_LOGIN);
            }

            // 验证支付密码格式
            if (!executeRequest.isPasswordValidFormat()) {
                Result<String> result = new Result<>(CoReturnFormat.PARAM_INVALID);
                result.setMessage("支付密码格式错误或解密失败");
                return result;
            }
            //校验用户是否设置支付密码
            WalletInfoVO walletInfo = buyerWalletService.getWalletInfo(user.getBuyerUserId());
            if (BeanUtil.isEmpty(walletInfo)) {
                return Result.failed(CoReturnFormat.WALLET_INIT_FAIL);
            }
            if (!walletInfo.getIsSetPayPassword()) {
                return Result.failed(CoReturnFormat.PAY_PASSWORD_NOT_SET);
            }
            WalletPayExecuteResult result = buyerWalletService.executeWalletPay(
                    user.getBuyerUserId(),
                    executeRequest.getOrderId(),
                    executeRequest.getType(),
                    executeRequest.getCollageId(),
                    executeRequest.getDecryptedPassword(),
                    getClientIpAddress(request)
            );

            if (result.isSuccess()) {
                return new Result(result.getMessage(), CoReturnFormat.SUCCESS, user.getWechatName(), "钱包支付执行", "");
            } else {
                return new Result(result.getMessage(), result.getErrorCode(), user.getWechatName(), "钱包支付执行", "");
            }
        } catch (Exception e) {
            log.error("钱包支付执行失败", e);
            return new Result(CoReturnFormat.SYS_ERROR);
        }
    }
}
